<template>
  <div style="border: 1px solid #ccc;height: 100%; width: 100%;" class="w-editor">
    <Toolbar :editor="editorRef" :default-config="toolbarConfig" :mode="mode" style="border-bottom: 1px solid #ccc;" />
    <Editor v-model="valueHtml" :default-config="editorConfig" :mode="mode" class="editor_custom "
      style="height: calc(100% - 42px); overflow-y: hidden;" @on-created="handleCreated" @on-change="handleChange"
      @on-destroyed="handleDestroyed" @on-focus="handleFocus" @on-blur="handleBlur" @custom-alert="customAlert"
      @custom-paste="customPaste" />
  </div>
</template>

<script setup>
import '@wangeditor/editor/dist/css/style.css'
import { userStore } from '@/store/user'
import { onBeforeUnmount, ref, shallowRef, onMounted, getCurrentInstance,watch } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
const { proxy } = getCurrentInstance()
const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  disabled: {
    type: Boolean,
    default: false
  }
})
const emit = defineEmits(['update:modelValue']);

const mode = 'default';

// 编辑器实例，必须用 shallowRef，重要！
const editorRef = shallowRef()

// const menu = editor.getAllMenuKeys()
// const bar = toolbar.getConfig().toolbarKeys
// 内容 HTML
const valueHtml = ref(props.modelValue)
watch(() => valueHtml.value, newValue => {
  emit('update:modelValue', newValue)
})

watch(() => props.modelValue, newValue => {
  valueHtml.value = newValue
})

const requestHeaders = ref({});


onMounted(() => {
  requestHeaders["x-token"] = userStore().token;
})

const toolbarConfig = {
  excludeKeys: [] // 此处不需要的工具栏选项
}

const editorConfig = {
  placeholder: '请输入内容...',
  MENU_CONF: {},
  hoverbarKeys: {
    'image': {
      // 清空 image 元素的 hoverbar
      menuKeys: []
    }
  }
}

// 上传图片
editorConfig.MENU_CONF['uploadImage'] = {
  server: '/api/sys/upload/image',
  fieldName: 'file',

  // 单个文件的最大体积限制，默认为 2M
  maxFileSize: 5 * 1024 * 1024, // 5M

  // 最多可上传几个文件，默认为 100
  maxNumberOfFiles: 20,

  // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
  // allowedFileTypes: ['image/png,image/jpeg,image/jpg'],

  // 自定义上传参数，例如传递验证的 token 等。参数会被添加到 formData 中，一起上传到服务端。
  meta: {
    pre: 'editor',
    watermark: true,
    maxWidth: 1200,
    maxHeight: 1200
  },

  // 将 meta 拼接到 url 参数中，默认 false
  metaWithUrl: false,

  // 自定义增加 http  header
  headers: requestHeaders,

  // 跨域是否传递 cookie ，默认为 false
  withCredentials: true,

  // 超时时间，默认为 10 秒
  timeout: 5 * 1000, // 5 秒
  // 上传之前触发
  onBeforeUpload(file) {
    // file 选中的文件，格式如 { key: file }
    console.debug(file);
    // 可以 return
    // 1. return file 或者 new 一个 file ，接下来将上传
    // 2. return false ，不上传这个 file
  },
  // 上传进度的回调函数
  onProgress(progress) {
    // progress 是 0-100 的数字
    console.debug('progress', progress)
  },
  // 单个文件上传成功之后
  onSuccess(file, res) {
    console.debug(`${file.name} 上传成功`, res)
  },
  // 自定义插入图片
  customInsert(res, insertFn) {
    // res 即服务端的返回结果
    // 从 res 中找到 url alt href ，然后插图图片
    if (res.ok) {
      insertFn(res.data, '', '');
    } else {
      proxy.$message.error(res.message);
    }
  },
  // 单个文件上传失败
  onFailed(file, res) {
    console.log(`${file.name} 上传失败`, res);
    proxy.$message.error(`${file.name} 上传出错`);
  },
  // 上传错误，或者触发 timeout 超时
  onError(file, err, res) {
    console.debug(`${file.name} 上传出错`, err, res);
    proxy.$message.error(`${file.name} 上传出错`);
  }
}
// 上传视频
editorConfig.MENU_CONF['uploadVideo'] = {
  server: '/api/sys/upload',
  fieldName: 'file',

  // 单个文件的最大体积限制，默认为 10M
  maxFileSize: 50 * 1024 * 1024, // 50M

  // 最多可上传几个文件，默认为 5
  maxNumberOfFiles: 3,

  // 选择文件时的类型限制，默认为 ['video/*'] 。如不想限制，则设置为 []
  allowedFileTypes: ['video/mp4'],

  // 自定义上传参数，例如传递验证的 token 等。参数会被添加到 formData 中，一起上传到服务端。
  meta: {
    pre: 'video'
  },

  // 将 meta 拼接到 url 参数中，默认 false
  metaWithUrl: false,

  // 自定义增加 http  header
  headers: requestHeaders,

  // 跨域是否传递 cookie ，默认为 false
  withCredentials: true,

  // 超时时间，默认为 30 秒
  timeout: 15 * 1000, // 15 秒

  // 视频不支持 base64 格式插入
  // 自定义插入视频
  customInsert(res, insertFn) {
    // res 即服务端的返回结果
    // 从 res 中找到 url ，然后插入视频
    if (res.ok) {
      insertFn(res.data, '', '');
    } else {
      proxy.$message.error(res.message);
    }
  },
  // 上传之前触发
  onBeforeUpload(file) {
    // file 选中的文件，格式如 { key: file }
    return file

    // 可以 return
    // 1. return file 或者 new 一个 file ，接下来将上传
    // 2. return false ，不上传这个 file
  },
  // 上传进度的回调函数
  onProgress(progress) {
    // progress 是 0-100 的数字
    console.debug('progress', progress)
  },
  // 单个文件上传成功之后
  onSuccess(file, res) {
    console.debug(`${file.name} 上传成功`, res)
  },
  // 单个文件上传失败
  onFailed(file, res) {
    console.log(`${file.name} 上传失败`, res);
    proxy.$message.error(`${file.name} 上传出错`);
  },
  // 上传错误，或者触发 timeout 超时
  onError(file, err, res) {
    console.debug(`${file.name} 上传出错`, err, res);
    proxy.$message.error(`${file.name} 上传出错`);
  }
}
// 组件销毁时，也及时销毁编辑器，重要！
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})

// 编辑器回调函数
const handleCreated = editor => {
  console.log('created', editor)
  editorRef.value = editor // 记录 editor 实例，重要！
  if (props.disabled) {
    editor.disable()
  } else {
    editor.enable()
  }
}
const handleChange = editor => {
  console.log('change:', editor.getHtml())

}
const handleDestroyed = editor => {
  console.log('destroyed', editor)
}
const handleFocus = editor => {
  console.log('focus', editor)
}
const handleBlur = editor => {
  console.log('blur', editor)
}
const customAlert = (info, type) => {
  proxy.$message.error(`${type} - ${info}`)
}
const customPaste = (editor, event, callback) => {
  console.log('ClipboardEvent 粘贴事件对象', event)

  // 自定义插入内容
  // editor.insertText('xxx')

  // 返回值（注意，vue 事件的返回值，不能用 return）
  // callback(false) // 返回 false ，阻止默认粘贴行为
  callback(true) // 返回 true ，继续默认的粘贴行为
}

</script>
<style  scoped>
.w-editor .w-e-scroll {
  overflow-y: hidden !important;
}

.w-editor .w-e-text-container [data-slate-editor] {
  overflow-y: auto !important;
  height: 100% !important;
}
</style>